package com._5704.website.config;

import com._5704.website.filter.JwtFilter;
import com._5704.website.shiro.MyRealm;
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
import org.apache.shiro.mgt.DefaultSubjectDAO;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {

    @Bean
    public ShiroFilterFactoryBean filterFactoryBean(@Qualifier("manager") DefaultWebSecurityManager manager){
        ShiroFilterFactoryBean filterBean = new ShiroFilterFactoryBean();
        // 设置securityManager
        filterBean.setSecurityManager(manager);
        // 设置自定义的拦截器
        Map<String, Filter> filterMap = new LinkedHashMap<>();
        filterMap.put("jwt",new JwtFilter());
        filterBean.setFilters(filterMap);
        /*
            anon 无需认证
            authc 需要认证
            user 需要记住我
            perms 权限
            role 角色
         */
        // 设置无权限时跳转的 url;
//        filterBean.setUnauthorizedUrl("/unauthorized");

        Map<String,String>filterRuleMap=new HashMap<>();

        // 所有请求通过我们自己的JWT Filter
        filterRuleMap.put("/unauthorized","anon");
        filterRuleMap.put("/user/getCode/**","anon");
        filterRuleMap.put("/user/login/**","anon");
        filterRuleMap.put("/user/modifyPwd/**","anon");
        filterRuleMap.put("/user/register/**","anon");
        filterRuleMap.put("/activity/getNum/**","anon");
        filterRuleMap.put("/activity/showMany/**","anon");
        filterRuleMap.put("/download/**","anon");
        filterRuleMap.put("/**","jwt");

        // 访问 /unauthorized/** 不通过JWTFilter
        filterBean.setFilterChainDefinitionMap(filterRuleMap);

        return filterBean;
    }

    /**
     * 生成SecurityManager
     * @param realm 自定义realm
     * @return
     */
    @Bean
    public DefaultWebSecurityManager manager(@Qualifier("realm") AuthorizingRealm realm){
        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
        // 注入自创建的realm
        manager.setRealm(realm);
        // 关闭session
        DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
        DefaultSessionStorageEvaluator sessionStorageEvaluator = new DefaultSessionStorageEvaluator();
        sessionStorageEvaluator.setSessionStorageEnabled(false);
        subjectDAO.setSessionStorageEvaluator(sessionStorageEvaluator);
        manager.setSubjectDAO(subjectDAO);
        return manager;
    }

    @Bean
    public AuthorizingRealm realm(){
        return new MyRealm();
    }

    /**
     * 开启Shiro的注解(如@RequiresRoles,@RequiresPermissions)
     * 配置以下两个bean(DefaultAdvisorAutoProxyCreator和AuthorizationAttributeSourceAdvisor)即可实现此功能
     * @return
     */
    @Bean
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("manager") DefaultWebSecurityManager manager){
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(manager);
        return authorizationAttributeSourceAdvisor;
    }


}
